package com.uniflow.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.uniflow.entity.DataSync;
import com.uniflow.mapper.DataSyncMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.*;

/**
 * 数据同步服务类
 */
@Service
public class DataSyncService extends ServiceImpl<DataSyncMapper, DataSync> {
    
    @Autowired
    private DataSyncMapper dataSyncMapper;
    
    @Autowired
    private ObjectMapper objectMapper;
    
    /**
     * 分页查询数据同步任务
     */
    public IPage<DataSync> getPageList(Integer pageNum, Integer pageSize, String syncType, String status,
                                       String category, String keyword, String tenantId) {
        Page<DataSync> page = new Page<>(pageNum, pageSize);
        IPage<DataSync> result = dataSyncMapper.selectPageList(page, syncType, status, category, keyword, tenantId);
        
        // 丰富数据同步任务信息
        result.getRecords().forEach(this::enrichDataSync);
        
        return result;
    }
    
    /**
     * 根据ID查询数据同步任务
     */
    public DataSync getById(String id, String tenantId) {
        DataSync dataSync = dataSyncMapper.selectById(id);
        if (dataSync != null && tenantId.equals(dataSync.getTenantId())) {
            enrichDataSync(dataSync);
            return dataSync;
        }
        return null;
    }
    
    /**
     * 根据名称查询数据同步任务
     */
    public DataSync getByName(String name, String tenantId) {
        DataSync dataSync = dataSyncMapper.selectByName(name, tenantId);
        if (dataSync != null) {
            enrichDataSync(dataSync);
        }
        return dataSync;
    }
    
    /**
     * 根据外部ID查询数据同步任务
     */
    public DataSync getByExternalId(String externalId, String tenantId) {
        DataSync dataSync = dataSyncMapper.selectByExternalId(externalId, tenantId);
        if (dataSync != null) {
            enrichDataSync(dataSync);
        }
        return dataSync;
    }
    
    /**
     * 根据业务键查询数据同步任务
     */
    public DataSync getByBusinessKey(String businessKey, String tenantId) {
        DataSync dataSync = dataSyncMapper.selectByBusinessKey(businessKey, tenantId);
        if (dataSync != null) {
            enrichDataSync(dataSync);
        }
        return dataSync;
    }
    
    /**
     * 根据同步类型查询数据同步任务
     */
    public List<DataSync> getBySyncType(String syncType, String tenantId) {
        List<DataSync> list = dataSyncMapper.selectBySyncType(syncType, tenantId);
        list.forEach(this::enrichDataSync);
        return list;
    }
    
    /**
     * 根据状态查询数据同步任务
     */
    public List<DataSync> getByStatus(String status, String tenantId) {
        List<DataSync> list = dataSyncMapper.selectByStatus(status, tenantId);
        list.forEach(this::enrichDataSync);
        return list;
    }
    
    /**
     * 根据分类查询数据同步任务
     */
    public List<DataSync> getByCategory(String category, String tenantId) {
        List<DataSync> list = dataSyncMapper.selectByCategory(category, tenantId);
        list.forEach(this::enrichDataSync);
        return list;
    }
    
    /**
     * 根据创建人查询数据同步任务
     */
    public List<DataSync> getByCreatedBy(String createdBy, String tenantId) {
        List<DataSync> list = dataSyncMapper.selectByCreatedBy(createdBy, tenantId);
        list.forEach(this::enrichDataSync);
        return list;
    }
    
    /**
     * 查询启用的数据同步任务
     */
    public List<DataSync> getEnabledSyncs(String tenantId) {
        List<DataSync> list = dataSyncMapper.selectEnabledSyncs(tenantId);
        list.forEach(this::enrichDataSync);
        return list;
    }
    
    /**
     * 查询可执行的数据同步任务
     */
    public List<DataSync> getExecutableSyncs(String tenantId) {
        List<DataSync> list = dataSyncMapper.selectExecutableSyncs(tenantId);
        list.forEach(this::enrichDataSync);
        return list;
    }
    
    /**
     * 查询需要执行的定时任务
     */
    public List<DataSync> getScheduledSyncs(String tenantId) {
        List<DataSync> list = dataSyncMapper.selectScheduledSyncs(LocalDateTime.now(), tenantId);
        list.forEach(this::enrichDataSync);
        return list;
    }
    
    /**
     * 查询正在运行的数据同步任务
     */
    public List<DataSync> getRunningSyncs(String tenantId) {
        List<DataSync> list = dataSyncMapper.selectRunningSyncs(tenantId);
        list.forEach(this::enrichDataSync);
        return list;
    }
    
    /**
     * 查询依赖的数据同步任务
     */
    public List<DataSync> getDependentSyncs(String syncId, String tenantId) {
        List<DataSync> list = dataSyncMapper.selectDependentSyncs(syncId, tenantId);
        list.forEach(this::enrichDataSync);
        return list;
    }
    
    /**
     * 创建数据同步任务
     */
    @Transactional
    public DataSync createDataSync(DataSync dataSync, String currentUserId) {
        // 设置基础信息
        dataSync.setId(UUID.randomUUID().toString());
        dataSync.setCreatedBy(currentUserId);
        dataSync.setCreatedTime(LocalDateTime.now());
        dataSync.setUpdatedBy(currentUserId);
        dataSync.setUpdatedTime(LocalDateTime.now());
        dataSync.setDeleted(false);
        dataSync.setVersion(1);
        
        // 设置默认值
        if (dataSync.getStatus() == null) {
            dataSync.setStatus("draft");
        }
        if (dataSync.getExecutionStatus() == null) {
            dataSync.setExecutionStatus("idle");
        }
        if (dataSync.getPriority() == null) {
            dataSync.setPriority(5);
        }
        if (dataSync.getTimeout() == null) {
            dataSync.setTimeout(3600);
        }
        if (dataSync.getRetryCount() == null) {
            dataSync.setRetryCount(3);
        }
        if (dataSync.getParallelCount() == null) {
            dataSync.setParallelCount(1);
        }
        if (dataSync.getBatchSize() == null) {
            dataSync.setBatchSize(1000);
        }
        
        // 设置排序
        if (dataSync.getSort() == null) {
            Integer maxSort = dataSyncMapper.getMaxSort(dataSync.getTenantId());
            dataSync.setSort(maxSort != null ? maxSort + 1 : 1);
        }
        
        // 序列化JSON字段
        serializeJsonFields(dataSync);
        
        dataSyncMapper.insert(dataSync);
        return getById(dataSync.getId(), dataSync.getTenantId());
    }
    
    /**
     * 更新数据同步任务
     */
    @Transactional
    public DataSync updateDataSync(DataSync dataSync, String currentUserId) {
        DataSync existing = dataSyncMapper.selectById(dataSync.getId());
        if (existing == null) {
            throw new RuntimeException("数据同步任务不存在");
        }
        
        // 更新基础信息
        dataSync.setUpdatedBy(currentUserId);
        dataSync.setUpdatedTime(LocalDateTime.now());
        dataSync.setVersion(existing.getVersion() + 1);
        
        // 序列化JSON字段
        serializeJsonFields(dataSync);
        
        dataSyncMapper.updateById(dataSync);
        return getById(dataSync.getId(), dataSync.getTenantId());
    }
    
    /**
     * 删除数据同步任务
     */
    @Transactional
    public boolean deleteDataSync(String id, String currentUserId, String tenantId) {
        DataSync dataSync = getById(id, tenantId);
        if (dataSync == null) {
            return false;
        }
        
        // 软删除
        dataSync.setDeleted(true);
        dataSync.setUpdatedBy(currentUserId);
        dataSync.setUpdatedTime(LocalDateTime.now());
        
        return dataSyncMapper.updateById(dataSync) > 0;
    }
    
    /**
     * 批量删除数据同步任务
     */
    @Transactional
    public boolean batchDeleteDataSyncs(List<String> ids, String currentUserId, String tenantId) {
        for (String id : ids) {
            deleteDataSync(id, currentUserId, tenantId);
        }
        return true;
    }
    
    /**
     * 启用数据同步任务
     */
    @Transactional
    public boolean enableDataSync(String id, String currentUserId, String tenantId) {
        return dataSyncMapper.updateStatus(id, "enabled", currentUserId) > 0;
    }
    
    /**
     * 禁用数据同步任务
     */
    @Transactional
    public boolean disableDataSync(String id, String currentUserId, String tenantId) {
        return dataSyncMapper.updateStatus(id, "disabled", currentUserId) > 0;
    }
    
    /**
     * 执行数据同步任务
     */
    @Transactional
    public boolean executeDataSync(String id, String currentUserId, String tenantId) {
        DataSync dataSync = getById(id, tenantId);
        if (dataSync == null || !dataSync.isExecutable()) {
            return false;
        }
        
        // 更新执行状态
        dataSyncMapper.updateExecutionStatus(id, "running", LocalDateTime.now(), null);
        
        // TODO: 实际执行数据同步逻辑
        
        return true;
    }
    
    /**
     * 停止数据同步任务
     */
    @Transactional
    public boolean stopDataSync(String id, String currentUserId, String tenantId) {
        return dataSyncMapper.updateExecutionStatus(id, "stopped", null, null) > 0;
    }
    
    /**
     * 重置数据同步任务
     */
    @Transactional
    public boolean resetDataSync(String id, String currentUserId, String tenantId) {
        return dataSyncMapper.updateExecutionStatus(id, "idle", null, null) > 0;
    }
    
    /**
     * 复制数据同步任务
     */
    @Transactional
    public DataSync copyDataSync(String id, String newName, String currentUserId, String tenantId) {
        DataSync original = getById(id, tenantId);
        if (original == null) {
            throw new RuntimeException("原数据同步任务不存在");
        }
        
        DataSync copy = new DataSync();
        // 复制属性（除了ID、名称、时间等）
        copy.setName(newName);
        copy.setDescription(original.getDescription());
        copy.setSyncType(original.getSyncType());
        copy.setSourceType(original.getSourceType());
        copy.setTargetType(original.getTargetType());
        copy.setSourceConfig(original.getSourceConfig());
        copy.setTargetConfig(original.getTargetConfig());
        copy.setMappingConfig(original.getMappingConfig());
        copy.setFilterConfig(original.getFilterConfig());
        copy.setTransformConfig(original.getTransformConfig());
        copy.setScheduleConfig(original.getScheduleConfig());
        copy.setPriority(original.getPriority());
        copy.setTimeout(original.getTimeout());
        copy.setRetryCount(original.getRetryCount());
        copy.setParallelCount(original.getParallelCount());
        copy.setBatchSize(original.getBatchSize());
        copy.setCategory(original.getCategory());
        copy.setTags(original.getTags());
        copy.setRemark(original.getRemark());
        copy.setExtendedProperties(original.getExtendedProperties());
        copy.setTenantId(original.getTenantId());
        
        return createDataSync(copy, currentUserId);
    }
    
    /**
     * 批量更新状态
     */
    @Transactional
    public boolean batchUpdateStatus(List<String> ids, String status, String currentUserId) {
        return dataSyncMapper.batchUpdateStatus(ids, status, currentUserId) > 0;
    }
    
    /**
     * 批量更新优先级
     */
    @Transactional
    public boolean batchUpdatePriority(List<String> ids, Integer priority, String currentUserId) {
        return dataSyncMapper.batchUpdatePriority(ids, priority, currentUserId) > 0;
    }
    
    /**
     * 批量更新分类
     */
    @Transactional
    public boolean batchUpdateCategory(List<String> ids, String category, String currentUserId) {
        return dataSyncMapper.batchUpdateCategory(ids, category, currentUserId) > 0;
    }
    
    /**
     * 批量更新排序
     */
    @Transactional
    public boolean batchUpdateSort(List<Map<String, Object>> sortData, String currentUserId) {
        return dataSyncMapper.batchUpdateSort(sortData, currentUserId) > 0;
    }
    
    /**
     * 检查名称是否可用
     */
    public boolean isNameAvailable(String name, String excludeId, String tenantId) {
        return dataSyncMapper.checkNameAvailable(name, excludeId, tenantId) == 0;
    }
    
    /**
     * 检查业务键是否存在
     */
    public boolean isBusinessKeyExists(String businessKey, String excludeId, String tenantId) {
        return dataSyncMapper.checkBusinessKeyExists(businessKey, excludeId, tenantId) > 0;
    }
    
    /**
     * 获取数据同步任务统计信息
     */
    public Map<String, Object> getStatistics(String tenantId) {
        return dataSyncMapper.getStatistics(tenantId);
    }
    
    /**
     * 按状态统计数据同步任务数量
     */
    public List<Map<String, Object>> getStatsByStatus(String tenantId) {
        return dataSyncMapper.getStatsByStatus(tenantId);
    }
    
    /**
     * 按同步类型统计数据同步任务数量
     */
    public List<Map<String, Object>> getStatsBySyncType(String tenantId) {
        return dataSyncMapper.getStatsBySyncType(tenantId);
    }
    
    /**
     * 按分类统计数据同步任务数量
     */
    public List<Map<String, Object>> getStatsByCategory(String tenantId) {
        return dataSyncMapper.getStatsByCategory(tenantId);
    }
    
    /**
     * 按创建人统计数据同步任务数量
     */
    public List<Map<String, Object>> getStatsByCreatedBy(String tenantId) {
        return dataSyncMapper.getStatsByCreatedBy(tenantId);
    }
    
    /**
     * 按时间统计数据同步任务数量
     */
    public List<Map<String, Object>> getStatsByTime(LocalDateTime startTime, LocalDateTime endTime, String timeUnit, String tenantId) {
        return dataSyncMapper.getStatsByTime(startTime, endTime, timeUnit, tenantId);
    }
    
    /**
     * 按月份统计数据同步任务数量
     */
    public List<Map<String, Object>> getStatsByMonth(Integer year, String tenantId) {
        return dataSyncMapper.getStatsByMonth(year, tenantId);
    }
    
    /**
     * 获取执行成功率统计
     */
    public Map<String, Object> getSuccessRateStats(String tenantId) {
        return dataSyncMapper.getSuccessRateStats(tenantId);
    }
    
    /**
     * 获取平均执行时间统计
     */
    public Map<String, Object> getAvgExecutionTimeStats(String tenantId) {
        return dataSyncMapper.getAvgExecutionTimeStats(tenantId);
    }
    
    /**
     * 获取失败任务统计
     */
    public Map<String, Object> getFailureStats(String tenantId) {
        return dataSyncMapper.getFailureStats(tenantId);
    }
    
    /**
     * 获取待执行任务数量
     */
    public Long getPendingCount(String tenantId) {
        return dataSyncMapper.getPendingCount(tenantId);
    }
    
    /**
     * 获取正在运行任务数量
     */
    public Long getRunningCount(String tenantId) {
        return dataSyncMapper.getRunningCount(tenantId);
    }
    
    /**
     * 获取今日新增任务数量
     */
    public Long getTodayAddedCount(String tenantId) {
        return dataSyncMapper.getTodayAddedCount(tenantId);
    }
    
    /**
     * 获取今日执行任务数量
     */
    public Long getTodayExecutedCount(String tenantId) {
        return dataSyncMapper.getTodayExecutedCount(tenantId);
    }
    
    /**
     * 获取本周统计
     */
    public Map<String, Object> getWeeklyStats(String tenantId) {
        return dataSyncMapper.getWeeklyStats(tenantId);
    }
    
    /**
     * 获取本月统计
     */
    public Map<String, Object> getMonthlyStats(String tenantId) {
        return dataSyncMapper.getMonthlyStats(tenantId);
    }
    
    /**
     * 查询数据同步任务分类列表
     */
    public List<String> getCategoryList(String tenantId) {
        return dataSyncMapper.selectCategoryList(tenantId);
    }
    
    /**
     * 查询数据同步任务类型列表
     */
    public List<String> getSyncTypeList(String tenantId) {
        return dataSyncMapper.selectSyncTypeList(tenantId);
    }
    
    /**
     * 查询数据源类型列表
     */
    public List<String> getSourceTypeList(String tenantId) {
        return dataSyncMapper.selectSourceTypeList(tenantId);
    }
    
    /**
     * 查询目标类型列表
     */
    public List<String> getTargetTypeList(String tenantId) {
        return dataSyncMapper.selectTargetTypeList(tenantId);
    }
    
    /**
     * 查询标签列表
     */
    public List<String> getTagList(String tenantId) {
        return dataSyncMapper.selectTagList(tenantId);
    }
    
    /**
     * 查询相关数据同步任务
     */
    public List<DataSync> getRelatedSyncs(String syncId, String tenantId) {
        List<DataSync> list = dataSyncMapper.selectRelatedSyncs(syncId, tenantId);
        list.forEach(this::enrichDataSync);
        return list;
    }
    
    /**
     * 查询依赖关系
     */
    public List<Map<String, Object>> getDependencies(String syncId, String tenantId) {
        return dataSyncMapper.selectDependencies(syncId, tenantId);
    }
    
    /**
     * 查询子任务
     */
    public List<DataSync> getChildSyncs(String parentId, String tenantId) {
        List<DataSync> list = dataSyncMapper.selectChildSyncs(parentId, tenantId);
        list.forEach(this::enrichDataSync);
        return list;
    }
    
    /**
     * 查询父任务
     */
    public DataSync getParentSync(String childId, String tenantId) {
        DataSync dataSync = dataSyncMapper.selectParentSync(childId, tenantId);
        if (dataSync != null) {
            enrichDataSync(dataSync);
        }
        return dataSync;
    }
    
    /**
     * 查询数据同步任务链
     */
    public List<DataSync> getSyncChain(String syncId, String tenantId) {
        List<DataSync> list = dataSyncMapper.selectSyncChain(syncId, tenantId);
        list.forEach(this::enrichDataSync);
        return list;
    }
    
    /**
     * 序列化JSON字段
     */
    private void serializeJsonFields(DataSync dataSync) {
        try {
            if (dataSync.getSourceConfigObj() != null) {
                dataSync.setSourceConfigJson(objectMapper.writeValueAsString(dataSync.getSourceConfigObj()));
            }
            if (dataSync.getTargetConfigObj() != null) {
                dataSync.setTargetConfigJson(objectMapper.writeValueAsString(dataSync.getTargetConfigObj()));
            }
            if (dataSync.getMappingConfigObj() != null) {
                dataSync.setMappingConfigJson(objectMapper.writeValueAsString(dataSync.getMappingConfigObj()));
            }
            if (dataSync.getFilterConfigObj() != null) {
                dataSync.setFilterConfigJson(objectMapper.writeValueAsString(dataSync.getFilterConfigObj()));
            }
            if (dataSync.getTransformConfigObj() != null) {
                dataSync.setTransformConfigJson(objectMapper.writeValueAsString(dataSync.getTransformConfigObj()));
            }
            if (dataSync.getScheduleConfigObj() != null) {
                dataSync.setScheduleConfigJson(objectMapper.writeValueAsString(dataSync.getScheduleConfigObj()));
            }
            if (dataSync.getExtendedPropertiesObj() != null) {
                dataSync.setExtendedPropertiesJson(objectMapper.writeValueAsString(dataSync.getExtendedPropertiesObj()));
            }
            if (dataSync.getTagsList() != null) {
                dataSync.setTags(String.join(",", dataSync.getTagsList()));
            }
        } catch (Exception e) {
            throw new RuntimeException("JSON序列化失败", e);
        }
    }
    
    /**
     * 反序列化JSON字段
     */
    private void deserializeJsonFields(DataSync dataSync) {
        try {
            if (StringUtils.hasText(dataSync.getSourceConfigJson())) {
                dataSync.setSourceConfigObj(objectMapper.readValue(dataSync.getSourceConfigJson(), new TypeReference<Map<String, Object>>() {}));
            }
            if (StringUtils.hasText(dataSync.getTargetConfigJson())) {
                dataSync.setTargetConfigObj(objectMapper.readValue(dataSync.getTargetConfigJson(), new TypeReference<Map<String, Object>>() {}));
            }
            if (StringUtils.hasText(dataSync.getMappingConfigJson())) {
                dataSync.setMappingConfigObj(objectMapper.readValue(dataSync.getMappingConfigJson(), new TypeReference<Map<String, Object>>() {}));
            }
            if (StringUtils.hasText(dataSync.getFilterConfigJson())) {
                dataSync.setFilterConfigObj(objectMapper.readValue(dataSync.getFilterConfigJson(), new TypeReference<Map<String, Object>>() {}));
            }
            if (StringUtils.hasText(dataSync.getTransformConfigJson())) {
                dataSync.setTransformConfigObj(objectMapper.readValue(dataSync.getTransformConfigJson(), new TypeReference<Map<String, Object>>() {}));
            }
            if (StringUtils.hasText(dataSync.getScheduleConfigJson())) {
                dataSync.setScheduleConfigObj(objectMapper.readValue(dataSync.getScheduleConfigJson(), DataSync.ScheduleConfig.class));
            }
            if (StringUtils.hasText(dataSync.getExtendedPropertiesJson())) {
                dataSync.setExtendedPropertiesObj(objectMapper.readValue(dataSync.getExtendedPropertiesJson(), new TypeReference<Map<String, Object>>() {}));
            }
            if (StringUtils.hasText(dataSync.getTags())) {
                dataSync.setTagsList(Arrays.asList(dataSync.getTags().split(",")));
            }
        } catch (Exception e) {
            // 忽略反序列化错误
        }
    }
    
    /**
     * 丰富数据同步任务信息
     */
    private void enrichDataSync(DataSync dataSync) {
        if (dataSync == null) {
            return;
        }
        
        // 反序列化JSON字段
        deserializeJsonFields(dataSync);
        
        // 设置计算字段
        dataSync.setSuccessRate(dataSync.getSuccessRate());
        dataSync.setFailureRate(dataSync.getFailureRate());
        dataSync.setAvgExecutionTime(dataSync.getAvgExecutionTime());
        dataSync.setExecutable(dataSync.isExecutable());
        dataSync.setNextExecutionTimeDesc(dataSync.getNextExecutionTimeDesc());
    }
    
    /**
     * 更新执行统计信息
     */
    @Transactional
    public boolean updateExecutionStats(String syncId, Map<String, Object> stats, String status, String errorMessage) {
        DataSync dataSync = dataSyncMapper.selectById(syncId);
        if (dataSync == null) {
            return false;
        }
        
        // 更新执行统计
        dataSync.setLastExecutionTime(LocalDateTime.now());
        dataSync.setLastExecutionStatus(status);
        if ("failed".equals(status)) {
            dataSync.setLastExecutionError(errorMessage);
        } else {
            dataSync.setLastExecutionError(null);
        }
        
        // 更新统计信息
        if (stats != null) {
            dataSync.setExecuteCount((Integer) stats.getOrDefault("executeCount", dataSync.getExecuteCount()));
            dataSync.setSuccessCount((Integer) stats.getOrDefault("successCount", dataSync.getSuccessCount()));
            dataSync.setFailureCount((Integer) stats.getOrDefault("failureCount", dataSync.getFailureCount()));
            dataSync.setExecuteDuration((Long) stats.getOrDefault("executeDuration", dataSync.getExecuteDuration()));
        }
        if (status != null) {
            dataSync.setExecuteStatus(status);
        }
        if (errorMessage != null) {
            dataSync.setLastErrorMessage(errorMessage);
        }
        
        return dataSyncMapper.updateById(dataSync) > 0;
    }
    
    /**
     * 更新执行状态
     */
    @Transactional
    public boolean updateExecutionStatus(String syncId, String status, String triggeredBy, String triggeredByName) {
        DataSync dataSync = dataSyncMapper.selectById(syncId);
        if (dataSync == null) {
            return false;
        }
        
        dataSync.setExecutionStatus(status);
        dataSync.setLastExecutionTime(LocalDateTime.now());
        dataSync.setLastExecutionStatus(status);
        dataSync.setUpdatedBy(triggeredBy);
        dataSync.setUpdatedByName(triggeredByName);
        dataSync.setUpdatedTime(LocalDateTime.now());
        
        return dataSyncMapper.updateById(dataSync) > 0;
    }
}